import { CharacterState, CharacterDir, CharacterDat, NpcDat, PlayerDat, ButtleDat, EnemyDat } from '../../Tools/QType';
import ScriptManager from "../../Tools/ScriptManager";




const {ccclass, property} = cc._decorator;
@ccclass
export default class Character extends cc.Component {
    protected _sprite:cc.Sprite; 
    
    get sprite(){
        if(!this._sprite){
            this._sprite = this.addComponent(cc.Sprite);                  
        }
        return this._sprite;
    }

    protected _animation:cc.Animation;
    get animation(){
        if(!this._animation){
            this._animation = this.addComponent(cc.Animation);
        }
        return this._animation;
    }

    protected _boxCollider:cc.BoxCollider;
    get boxCollider(){
        if(!this._boxCollider){
            this._boxCollider = this.addComponent(cc.BoxCollider);            
        }
        return this._boxCollider;
    }


    /** 状态 */
    protected _state:CharacterState=CharacterState.Idle;
    set state(value){
        if(this.state==value)return;
        this._state = value;        
        this.playAnim();
    }
    get state(){
        return this._state;
    }

    /** 方向 */
    protected _dir:CharacterDir = CharacterDir.Down;
    set dir(value){
        if(this.dir==value)return;
        this._dir = value;
        this.playAnim();
    }
    get dir(){
        return this._dir;
    }
   
    
    /** 速度 */
    protected speed:number=3;
    /** 角色数据 */    
    protected dat:CharacterDat|NpcDat|PlayerDat|ButtleDat|EnemyDat;

    onLoad(){
        this.node.name  =this.dat.name;        
        this.node.x = this.dat.x;
        this.node.y = this.dat.y;   
        this.node.on("position-changed",()=>{})
    }

    /** 移动 */        
    move(dt){     
        let p1 = this.node.position;
        let p2 = this.getDirVec2().mul(this.speed);
        let p3 = p1.add(p2);
        //人物的脚点(4点矩形)
        let footer = [
            cc.v2(p3.x-10,p3.y),
            cc.v2(p3.x+10,p3.y),
            cc.v2(p3.x-10,p3.y+20),
            cc.v2(p3.x+10,p3.y+20)
        ];                                
        let canMove=true;
        for(let i=0;i<footer.length;i++){
            if(!ScriptManager.Instance.MapTerrain.checkMove(footer[i])){
                canMove = false;
                break;
            }    
        }
        if(canMove){
            this.node.position = p3;
        }            
    }
    
    protected getDirVec2(){
        let row = [cc.v2(0,1),cc.v2(0,-1),cc.v2(-1,0),cc.v2(1,0)];
        return row[this.dir];
    }
    /**
     * 设置角色数据     
     */
    setDat(dat){
        this.dat = dat;  
        this.dat._node = this.node;                        
        this.dir = dat.dir;
        this.state = dat.state||CharacterState.Idle;
        this.boxCollider.size = cc.size(10,10);
        this.boxCollider.offset = cc.v2(0,5);
    }

    /**
     * 改变状态或方向后，修改动画
     */
    playAnim(){
        let state = this.state;
        let dir = this.dir;    
        
        switch(state){            
            case CharacterState.Move:
            case CharacterState.AutoMove:
            case CharacterState.Idle:
                let s = this.state;
                if(s==CharacterState.AutoMove){
                    s = CharacterState.Move;
                }
                let name = s+"_"+this.dir                
                this.animation.play(name);
            break;                               
            default:
                name = state+"_"+this.dir;                
                this.animation.play(name)
            break;
        }        
    }

    /**
     * 自动寻路
     */
    AutoMove(p:any){                
        if( !(p instanceof cc.Vec2) ){            
            p = new cc.Vec2(p.x,p.y)
        }
        this.node.stopAllActions();
        
        let paths = ScriptManager.Instance.MapTerrain.AutoFindPath(this.node.position,p);      
        let as = [];
     
        
        // let node = new cc.Node;
        // node.setParent(this.node.parent);
        // let g = node.addComponent(cc.Graphics);
        // g.moveTo(this.node.position.x,this.node.position.y)
        // let tempP = cc.find("Canvas/p0").getComponent(cc.Sprite);
        
        this.state = CharacterState.AutoMove;
        for(let i=0;i<paths.length;i++){
            let item = paths[i];
           
            // let node = new cc.Node;
            // node.position = item;
            // node.setContentSize(5,5);
            // node.parent = this.node.parent;
            // let sp = node.addComponent(cc.Sprite)
            // sp.spriteFrame = tempP.spriteFrame;
            // g.lineTo(item.x,item.y)


            let a = cc.callFunc(()=>{
                //0上 180下 //左90  //右-90
                let angle = cc.Vec2.UP.signAngle(item.sub(this.node.position))*180/Math.PI
                let aInt = Math.round(angle/10)*10;
                switch(aInt){
                    case 0:
                        this.dir = CharacterDir.Up
                    break
                    case 180:                    
                        this.dir = CharacterDir.Down
                    break
                    case 90:
                        this.dir = CharacterDir.Left;
                    break
                    case -90:
                        this._dir = CharacterDir.Left;
                    break
                    default:
                        cc.log("调试角度",angle,aInt);
                    break
                }                           
            })
            
            let b = cc.moveTo(0.2,item);            
            as.push(a,b)
        }
        //g.stroke();                
        as.push(
            cc.callFunc(()=>{                                
                this.state = CharacterState.Idle  
                this.AutoMoveEnd();
            })
        )

        let seq = cc.sequence(as);
        this.node.runAction(seq)
    }


    /**
     * 根据角度获取方向
     */
    getDirForAngle(angle:number){
        let dir:CharacterDir
        if( angle<45 && angle>=-45){
            dir = CharacterDir.Up
        }else if( angle<-45 && angle>=-135 ){            
            dir = CharacterDir.Right
        }else if( (angle<-135 && angle>=-180) || (angle>135 && angle<=180)  ){
            dir = CharacterDir.Down
        }else if( angle>45 && angle<=135 ){
            dir = CharacterDir.Left
        }
        return dir
    }

    AutoMoveEnd(){
        let event = new cc.Event.EventCustom("AutoMoveEnd",true);
        this.node.dispatchEvent(event);
    }

}